<?php

/**
 * Louder Cache
 *
 * LICENSE
 *
 * This source file is subject to the New BSD License that is bundled
 * with this package in the file docs/LICENSE.txt.
 *
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to info@loudertechnology.com so we can send you a copy immediately.
 *
 * @category Louder
 * @package CacheStorage
 * @copyright Copyright (c) 2005-2009 Andres Felipe Gutierrez (gutierrezandresfelipe at gmail.com)
 * @license New BSD License
 */

/**
 * Proxy a los adaptadores de almacenamiento
 *
 * @category Louder
 * @package CacheStorage
 * @copyright Copyright (c) 2005-2009 Andres Felipe Gutierrez (gutierrezandresfelipe at gmail.com)
 * @license New BSD License
 */
class CacheStorage {

	/**
	 * Adaptador de almacenamiento
	 *
	 * @var CacheAdapter
	 */
	private static $_adapter;

	/**
	 * Inicializa el administrador de cache
	 *
	 * @access public
	 * @static
	 */
	public static function initStorage(){
		$config = new ConfigReader("config-server.xml");
		$storageHandler = $config->getAttributeFromNode("storage-handler", "name");
		if(interface_exists("CacheStorageInterface")==false){
			require "Library/Louder/CacheStorage/Interface.php";
		}
		$className = $storageHandler."CacheStorage";
		if(!class_exists($className)){
			require "Library/Louder/CacheStorage/Adapters/".ucfirst($storageHandler).".php";
		}
		$settings = $config->getAttributesFromNode("storage-options");
		self::$_adapter = new $className($settings);
	}

	/**
	 * Devuelve el nodo raiz del arbol
	 *
	 * @access public
	 * @return CacheNode
	 * @static
	 */
	public static function getRootNode(){
		return new CacheNode($node, 0);
	}

	/**
	 * Agrega nodos a otro nodo
	 *
	 * @access public
	 * @param int $id
	 * @param array $items
	 * @return CacheNode
	 * @static
	 */
	public static function addChild($id, $items){
		#self::_gainLock();
		$nodeInfo = self::$_adapter->addChildById($id, $items);
		$node = new CacheNode($node['id']);
		#self::_safeUnlock();
		return $node;
	}

	/**
	 * Agrega un atributo a un nodo
	 *
	 * @param int $id
	 * @param string $index
	 * @param mixed $value
	 * @return boolean
	 */
	public function addNodeAttribute($id, $index, $value){
		return self::$_adapter->addNodeAttribute($id, $index, $value);
	}

	/**
	 * Obtiene el valor de un atributo
	 *
	 * @param int $id
	 * @param string $index
	 * @return mixed
	 */
	public function getNodeAttribute($id, $index){
		return self::$_adapter->getNodeAttribute($id, $index);
	}

	/**
	 * Realiza una consulta en el arbol y devuelve los resultados
	 *
	 * @access public
	 * @param string $path
	 * @return CacheNode
	 * @static
	 */
	public static function query($path){
		$result = self::$_adapter->getNodeByPath($path);
		if(is_null($result)){
			return null;
		} else {
			return new CacheNode($result['id']);
		}
	}

	static function gt(){
		return self::$_adapter->gt();
	}

	/**
	 * Gana un bloqueo sobre el arbol
	 *
	 * @access public
	 * @static
	 */
	static private function _gainLock(){
		while(self::$_adapter->getLock()==true){
			usleep(0005000);
		}
		self::$_adapter->lock();
	}

	/**
	 * Realiza un desbloqueo seguro del arbol
	 *
	 * @access public
	 * @static
	 */
	static private function _safeUnlock(){
		if(self::$_adapter->getLock()==true){
			self::$_adapter->lock();
		}
	}

}